1.作用域

执行上下文 (变量提前、函数声明提前、确定this值、arguments)

    范围:一段<script>或者一个函数(都会生成一个执行上下文)

    全局(一段<script>):变量定义、函数声明
    函数:变量定义、函数声明、this、arguments(参数集合)

变量提前代码解析:

consol.log(a) //undefined
var a = 100
(执行过程:(1)变量定义提前 var a = undefined
          (2)consol.log(a) //undefined
          (3)a = 100 //赋值
)

函数声明提前代码解析:

函数声明:function fn(){}
函数表达式:var fn = function(){}

fn() 
function fn(){} 
(执行过程:(1)function fn(){}
         (2)fn() )
              
fn() 
var fn = function(){}             
(执行过程:(1)var fn = undefined
         (2)fn() 
         (3)fn = function(){}   )        

this (执行时才能确认,定义时无法确认)

this执行场景:

(1)作为构造函数执行
   function Foo(name){
       // this = {}
       this.name = name
       // returen this
    }
    var fn = new Foo("lala")
    
(2)作为对象属性执行
   var obj = {
       name:"lala",
       printName: function(){
           console.log(this.name)
       }
   }
   obj.printName();//  对象属性执行,this就是对象obj
            
(3)作为普通函数执行
   function fn(){
       console.log(this) // window
   }
   
(4)call、apply、bind
   function fn(name,age){
       alert(name)
       console.log(this) //{x:100}
   }
   fn.call({x:100},"lala",13) //{x:100}当this
   fn.apply({x:100},["lala",13])

   var fn = function fn(name,age){
       alert(name)
       console.log(this) //
   }.bind({x:100}) //函数表达式.bind
   fn("lala",13) 
   

作用域 JS没有块级作用域,只有函数和全局作用域

(1)无块级作用域
    if(true){
        var a = 10
    }     
    console.log(name) //name  
    
(2)函数作用域和全局作用域
    var a = 10 //全局作用域(都可以访问获取)
    function fn(){
        var a = 20
        console.log(a) // 20 函数作用域(从外面得不到,也改不了)
    }
    console.log(a) //10
    fn()

2.作用域链

自由变量:当前作用域没有定义的变量
函数父级作用域:函数定义时的作用域(函数在哪定义,父级作用域在哪)

var a  = 10
function fn1(){
    var b = 20
    function fn2(){
        var c = 30
        console.log(a) //10 a是自由变量
        console.log(b) //20 b是自由变量
        console.log(c)
    }
    fn2()
}
fn1()
作用域链:自由变量不断向父级作用域中寻找,形成链式

3.闭包
应用场景:(1)函数作为返回值

function fn(){
    var a = 10
    return function(){
        console.log(a) //10
    }
}
var f1 = fn()
var a = 20
f1()

(2)函数作为参数传递(函数传递到另一个函数中执行)

function fn(){
    var a = 10
    return function(){
        console.log(a) //10
    }
}
var f1 = fn()
function f2(f){
    var a = 20
    f()
}
f2(f1)

相关问题:

1.理解变量提升

  变量定义、函数声明被提升(到包含他们作用域的最顶端)
 
2.创建10个a标签,点击时弹出对应的序号

  var i 
  for(i = 0; i < 10; i++){
     (function(i){
          var a = document.creatElement("a")
          a.innerHtml = i
          a.addEventListerner("click",function(e){
              e.preventDefault()
              alert(i)
          })
          document.body.appendChild(a)
     })()
  } 
 
 3.实际开发中闭包的应用:封装变量,收敛权限 
  
   function isFirst(num){
       var _list = [] // _list 下划线表示私有的
       return function(){
           if(_list.indexOf(num)){
               return false
           }else{
               _list.push(num)
               return true
           }
       }
   }
   var first = isFirst()
   first(10) // true
   first(10) // false
   first(20) // true

 

艿厝
18 声望3 粉丝